home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / shadow-3.1.4 / grent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-05  |  9.7 KB  |  528 lines

  1. /*
  2.  * Copyright 1990, 1991, 1992, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Permission is granted to copy and create derivative works for any
  6.  * non-commercial purpose, provided this copyright notice is preserved
  7.  * in all copies of source code, or included in human readable form
  8.  * and conspicuously displayed on all copies of object code or
  9.  * distribution media.
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <grp.h>
  14. #ifdef    BSD
  15. #include <strings.h>
  16. #define    strchr    index
  17. #define    strrchr    rindex
  18. #else    /* !BSD */
  19. #include <string.h>
  20. #endif    /* BSD */
  21. #include "config.h"
  22.  
  23. #ifdef    AUTOSHADOW
  24. #include "shadow.h"
  25. #endif    /* AUTOSHADOW */
  26.  
  27. #ifdef    NDBM
  28. #include <ndbm.h>
  29. #include <fcntl.h>
  30. DBM    *gr_dbm;
  31. int    gr_dbm_mode = -1;
  32. #endif    /* NDBM */
  33.  
  34. #ifndef    lint
  35. static    char    sccsid[] = "@(#)grent.c    3.11    20:36:44    3/7/92";
  36. #endif    /* !lint */
  37.  
  38. #define    NFIELDS    4
  39. #define    MAXMEM    1024
  40.  
  41. static    char    grpbuf[4*BUFSIZ];
  42. static    char    *grpfields[NFIELDS];
  43. static    char    *members[MAXMEM+1];
  44. static    struct    group    grent;
  45.  
  46. static    FILE    *grpfp;
  47. static    char    *grpfile = GRPFILE;
  48. #ifdef    NDBM
  49. static    int    dbmopened;
  50. static    int    dbmerror;
  51. #endif    /* NDBM */
  52.  
  53. char *
  54. fgetsx (buf, cnt, f)
  55. char    *buf;
  56. int    cnt;
  57. FILE    *f;
  58. {
  59.     char    *cp = buf;
  60.     char    *ep;
  61.  
  62.     while (cnt > 0) {
  63.         if (fgets (cp, cnt, f) == 0)
  64.             if (cp == buf)
  65.                 return 0;
  66.             else
  67.                 break;
  68.  
  69.         if ((ep = strrchr (cp, '\\')) && *(ep + 1) == '\n') {
  70.             if ((cnt -= ep - cp) > 0)
  71.                 *(cp = ep) = '\0';
  72.         } else
  73.             break;
  74.     }
  75.     return buf;
  76. }
  77.  
  78. int
  79. fputsx (s, stream)
  80. char    *s;
  81. FILE    *stream;
  82. {
  83.     int    i;
  84.  
  85.     for (i = 0;*s;i++, s++) {
  86.         if (putc (*s, stream) == EOF)
  87.             return EOF;
  88.  
  89.         if (i > (BUFSIZ/2)) {
  90.             if (putc ('\\', stream) == EOF ||
  91.                 putc ('\n', stream) == EOF)
  92.                 return EOF;
  93.  
  94.             i = 0;
  95.         }
  96.     }
  97.     return 0;
  98. }
  99.  
  100. static char **
  101. list (s)
  102. char    *s;
  103. {
  104.     int    nmembers = 0;
  105.  
  106.     while (s && *s) {
  107.         members[nmembers++] = s;
  108.         if (s = strchr (s, ','))
  109.             *s++ = '\0';
  110.     }
  111.     members[nmembers] = (char *) 0;
  112.     return members;
  113. }
  114.  
  115. struct    group    *sgetgrent (buf)
  116. char    *buf;
  117. {
  118.     int    i;
  119.     char    *cp;
  120.  
  121.     strncpy (grpbuf, buf, sizeof grpbuf);
  122.     grpbuf[sizeof grpbuf - 1] = '\0';
  123.     if (cp = strrchr (grpbuf, '\n'))
  124.         *cp = '\0';
  125.  
  126.     for (cp = grpbuf, i = 0;i < NFIELDS && cp;i++) {
  127.         grpfields[i] = cp;
  128.         if (cp = strchr (cp, ':'))
  129.             *cp++ = 0;
  130.     }
  131.     if (i < (NFIELDS-1) || *grpfields[2] == '\0')
  132.         return ((struct group *) 0);
  133.  
  134.     grent.gr_name = grpfields[0];
  135.     grent.gr_passwd = grpfields[1];
  136.     grent.gr_gid = atoi (grpfields[2]);
  137.     grent.gr_mem = list (grpfields[3]);
  138.  
  139.     return (&grent);
  140. }
  141.  
  142. int
  143. putgrent (g, f)
  144. struct    group    *g;
  145. FILE    *f;
  146. {
  147.     int    i;
  148.     char    *cp;
  149.     char    buf[BUFSIZ*4];
  150.  
  151.     if (! g || ! f)
  152.         return -1;
  153.  
  154.     sprintf (buf, "%s:%s:%d:", g->gr_name, g->gr_passwd, g->gr_gid);
  155.     if (g->gr_mem) {
  156.         cp = strchr (buf, '\0');
  157.         for (i = 0;g->gr_mem[i];i++) {
  158.             if ((cp - buf) + strlen (g->gr_mem[i]) + 2
  159.                     >= sizeof buf)
  160.                 return -1;
  161.  
  162.             if (i > 0) {
  163.                 strcpy (cp, ",");
  164.                 cp++;
  165.             }
  166.             strcpy (cp, g->gr_mem[i]);
  167.             cp = strchr (cp, '\0');
  168.         }
  169.         strcat (cp, "\n");
  170.     } else
  171.         strcat (buf, "\n");
  172.  
  173.     if (fputsx (buf, f) == EOF || ferror (f))
  174.         return -1;
  175.  
  176.     return 0;
  177. }
  178.  
  179. #ifdef    GETGRENT
  180.  
  181. /*
  182.  * fgetgrent - get a group file entry from a stream
  183.  *
  184.  * fgetgrent() reads the next line from a group file formatted stream
  185.  * and returns a pointer to the group structure for that line.
  186.  */
  187.  
  188. struct    group    *fgetgrent (fp)
  189. FILE    *fp;
  190. {
  191.     char    buf[BUFSIZ*4];
  192.     char    *cp;
  193.  
  194.     if (fgetsx (buf, sizeof buf, fp) != (char *) 0) {
  195.         if (cp = strchr (buf, '\n'))
  196.             *cp = '\0';
  197.  
  198.         return (sgetgrent (buf));
  199.     }
  200.     return 0;
  201. }
  202.  
  203. /*
  204.  * endgrent - close a group file
  205.  *
  206.  * endgrent() closes the group file if open.
  207.  */
  208.  
  209. #ifdef    SVR4
  210. void
  211. #else
  212. int
  213. #endif
  214. endgrent ()
  215. {
  216.     if (grpfp)
  217.         if (fclose (grpfp))
  218. #ifdef    SVR4
  219.             return;
  220. #else
  221.             return -1;
  222. #endif
  223.     grpfp = 0;
  224. #ifdef    NDBM
  225.     if (dbmopened && gr_dbm) {
  226.         dbm_close (gr_dbm);
  227.         gr_dbm = 0;
  228.     }
  229.     dbmopened = 0;
  230.     dbmerror = 0;
  231. #endif    /* NDBM */
  232. #ifndef    SVR4
  233.     return 0;
  234. #endif
  235. }
  236.  
  237. /*
  238.  * getgrent - get a group entry from the group file
  239.  *
  240.  * getgrent() opens the group file, if not already opened, and reads
  241.  * a single entry.  NULL is returned if any errors are encountered reading
  242.  * the group file.
  243.  */
  244.  
  245. struct    group    *getgrent ()
  246. {
  247. #ifdef    SVR4
  248.     if (! grpfp)
  249.         setgrent ();
  250. #else
  251.     if (! grpfp && setgrent ())
  252.         return 0;
  253. #endif
  254.     return fgetgrent (grpfp);
  255. }
  256.  
  257. /*
  258.  * getgrgid - locate the group entry for a given GID
  259.  *
  260.  * getgrgid() locates the first group file entry for the given GID.
  261.  * If there is a valid DBM file, the DBM files are queried first for
  262.  * the entry.  Otherwise, a linear search is begun of the group file
  263.  * searching for an entry which matches the provided GID.
  264.  */
  265.  
  266. struct    group    *getgrgid (gid)
  267. int    gid;
  268. {
  269.     struct    group    *grp;
  270. #ifdef NDBM
  271.     datum    key;
  272.     datum    content;
  273.     int    cnt;
  274.     int    i;
  275.     char    *cp;
  276.     char    grpkey[64];
  277. #endif    /* NDBM */
  278. #ifdef    AUTOSHADOW
  279.     struct    sgrp    *sgrp;
  280. #endif    /* AUTOSHADOW */
  281.  
  282. #ifdef    SVR4
  283.     setgrent ();
  284. #else
  285.     if (setgrent ())
  286.         return 0;
  287. #endif
  288. #ifdef NDBM
  289.  
  290.     /*
  291.      * If the DBM file are now open, create a key for this GID and
  292.      * try to fetch the entry from the database.  A matching record
  293.      * will be unpacked into a static structure and returned to
  294.      * the user.
  295.      */
  296.  
  297.     if (dbmopened) {
  298.         grent.gr_gid = gid;
  299.         key.dsize = sizeof grent.gr_gid;
  300.         key.dptr = (char *) &grent.gr_gid;
  301.         content = dbm_fetch (gr_dbm, key);
  302.         if (content.dptr == 0)
  303.             return 0;
  304.  
  305.         if (content.dsize == sizeof (int)) {
  306.             memcpy ((char *) &cnt, content.dptr, content.dsize);
  307.             for (cp = grpbuf, i = 0;i < cnt;i++) {
  308.                 memcpy (grpkey, (char *) &i, (int) sizeof i);
  309.                 memcpy (grpkey + sizeof i,
  310.                     (char *) &grent.gr_gid,
  311.                     (int) sizeof grent.gr_gid);
  312.  
  313.                 key.dsize = sizeof i + sizeof grent.gr_gid;
  314.                 key.dptr = grpkey;
  315.  
  316.                 content = dbm_fetch (gr_dbm, key);
  317.                 if (content.dptr == 0)
  318.                     return 0;
  319.  
  320.                 memcpy (cp, content.dptr, content.dsize);
  321.                 cp += content.dsize;
  322.             }
  323.             grent.gr_mem = members;
  324.             gr_unpack (grpbuf, cp - grpbuf, &grent);
  325. #ifdef    AUTOSHADOW
  326.             if (sgrp = getsgnam (grent.gr_name)) {
  327.                 grent.gr_passwd = sgrp->sg_passwd;
  328.                 grent.gr_mem = sgrp->sg_mem;
  329.             }
  330. #endif    /* AUTOSHADOW */
  331.             return &grent;
  332.         } else {
  333.             grent.gr_mem = members;
  334.             memcpy (grpbuf, content.dptr, content.dsize);
  335.             gr_unpack (grpbuf, content.dsize, &grent);
  336. #ifdef    AUTOSHADOW
  337.             if (sgrp = getsgnam (grent.gr_name)) {
  338.                 grent.gr_passwd = sgrp->sg_passwd;
  339.                 grent.gr_mem = sgrp->sg_mem;
  340.             }
  341. #endif    /* AUTOSHADOW */
  342.             return &grent;
  343.         }
  344.     }
  345. #endif    /* NDBM */
  346.     /*
  347.      * Search for an entry which matches the GID.  Return the
  348.      * entry when a match is found.
  349.      */
  350.  
  351.     while (grp = getgrent ())
  352.         if (grp->gr_gid == gid)
  353.             break;
  354.  
  355. #ifdef    AUTOSHADOW
  356.     if (grp) {
  357.         if (sgrp = getsgnam (grent.gr_name)) {
  358.             grp->gr_passwd = sgrp->sg_passwd;
  359.             grp->gr_mem = sgrp->sg_mem;
  360.         }
  361.     }
  362. #endif    /* AUTOSHADOW */
  363.     return grp;
  364. }
  365.  
  366. struct    group    *getgrnam (name)
  367. char    *name;
  368. {
  369.     struct    group    *grp;
  370. #ifdef NDBM
  371.     datum    key;
  372.     datum    content;
  373.     int    cnt;
  374.     int    i;
  375.     char    *cp;
  376.     char    grpkey[64];
  377. #endif    /* NDBM */
  378. #ifdef    AUTOSHADOW
  379.     struct    sgrp    *sgrp;
  380. #endif    /* AUTOSHADOW */
  381.  
  382. #ifdef    SVR4
  383.     setgrent ();
  384. #else
  385.     if (setgrent ())
  386.         return 0;
  387. #endif
  388. #ifdef NDBM
  389.  
  390.     /*
  391.      * If the DBM file are now open, create a key for this GID and
  392.      * try to fetch the entry from the database.  A matching record
  393.      * will be unpacked into a static structure and returned to
  394.      * the user.
  395.      */
  396.  
  397.     if (dbmopened) {
  398.         key.dsize = strlen (name);
  399.         key.dptr = name;
  400.         content = dbm_fetch (gr_dbm, key);
  401.         if (content.dptr == 0)
  402.             return 0;
  403.  
  404.         if (content.dsize == sizeof (int)) {
  405.             memcpy ((char *) &cnt, content.dptr, content.dsize);
  406.             for (cp = grpbuf, i = 0;i < cnt;i++) {
  407.                 memcpy (grpkey, (char *) &i, (int) sizeof i);
  408.                 strcpy (grpkey + sizeof i, name);
  409.  
  410.                 key.dsize = sizeof i + strlen (name);
  411.                 key.dptr = grpkey;
  412.  
  413.                 content = dbm_fetch (gr_dbm, key);
  414.                 if (content.dptr == 0)
  415.                     return 0;
  416.  
  417.                 memcpy (cp, content.dptr, content.dsize);
  418.                 cp += content.dsize;
  419.             }
  420.             grent.gr_mem = members;
  421.             gr_unpack (grpbuf, cp - grpbuf, &grent);
  422. #ifdef    AUTOSHADOW
  423.             if (sgrp = getsgnam (grent.gr_name)) {
  424.                 grent.gr_passwd = sgrp->sg_passwd;
  425.                 grent.gr_mem = sgrp->sg_mem;
  426.             }
  427. #endif    /* AUTOSHADOW */
  428.             return &grent;
  429.         } else {
  430.             grent.gr_mem = members;
  431.             memcpy (grpbuf, content.dptr, content.dsize);
  432.             gr_unpack (grpbuf, content.dsize, &grent);
  433. #ifdef    AUTOSHADOW
  434.             if (sgrp = getsgnam (grent.gr_name)) {
  435.                 grent.gr_passwd = sgrp->sg_passwd;
  436.                 grent.gr_mem = sgrp->sg_mem;
  437.             }
  438. #endif    /* AUTOSHADOW */
  439.             return &grent;
  440.         }
  441.     }
  442. #endif    /* NDBM */
  443.     /*
  444.      * Search for an entry which matches the name.  Return the
  445.      * entry when a match is found.
  446.      */
  447.  
  448.     while (grp = getgrent ())
  449.         if (strcmp (grp->gr_name, name) == 0)
  450.             break;
  451.  
  452. #ifdef    AUTOSHADOW
  453.     if (grp) {
  454.         if (sgrp = getsgnam (grent.gr_name)) {
  455.             grp->gr_passwd = sgrp->sg_passwd;
  456.             grp->gr_mem = sgrp->sg_mem;
  457.         }
  458.     }
  459. #endif    /* AUTOSHADOW */
  460.     return grp;
  461. }
  462.  
  463. /*
  464.  * setgrent - open the group file
  465.  *
  466.  * setgrent() opens the system group file, and the DBM group files
  467.  * if they are present.  The system group file is rewound if it was
  468.  * open already.
  469.  */
  470.  
  471. #ifdef    SVR4
  472. void
  473. #else
  474. int
  475. #endif
  476. setgrent ()
  477. {
  478. #ifdef    NDBM
  479.     int    mode;
  480. #endif    /* NDBM */
  481.  
  482.     if (! grpfp) {
  483.         if (! (grpfp = fopen (grpfile, "r")))
  484. #ifdef    SVR4
  485.             return;
  486. #else
  487.             return -1;
  488. #endif
  489.     } else {
  490.         if (fseek (grpfp, 0L, 0) != 0)
  491. #ifdef    SVR4
  492.             return;
  493. #else
  494.             return -1;
  495. #endif
  496.     }
  497.  
  498.     /*
  499.      * Attempt to open the DBM files if they have never been opened
  500.      * and an error has never been returned.
  501.      */
  502.  
  503. #ifdef NDBM
  504.     if (! dbmerror && ! dbmopened) {
  505.         char    dbmfiles[BUFSIZ];
  506.  
  507.         strcpy (dbmfiles, grpfile);
  508.         strcat (dbmfiles, ".pag");
  509.         if (gr_dbm_mode == -1)
  510.             mode = O_RDONLY;
  511.         else
  512.             mode = (gr_dbm_mode == O_RDONLY ||
  513.                 gr_dbm_mode == O_RDWR) ? gr_dbm_mode:O_RDONLY;
  514.  
  515.         if (access (dbmfiles, 0) ||
  516.             (! (gr_dbm = dbm_open (grpfile, mode, 0))))
  517.             dbmerror = 1;
  518.         else
  519.             dbmopened = 1;
  520.     }
  521. #endif    /* NDBM */
  522. #ifndef    SVR4
  523.     return 0;
  524. #endif
  525. }
  526.  
  527. #endif    /* GRENT */
  528.